//
//  SignalSlot.h
//  smallworld
//
//  Created by 周俊 on 14/11/25.
//
//

#ifndef __smallworld__SignalSlot__
#define __smallworld__SignalSlot__

#include <functional>
#include <map>
#include <list>
#include "Macro.h"

TSP_NS_START

typedef std::function<void(void*)> SLOT_FUNCTION;
class Signal;

class Slot
{
    friend class Signal;
public:
    static Slot* createSlot(const SLOT_FUNCTION& slot_function, int priority, bool repeat);

    void retain();
    void release();

    inline bool isEnable()
    {
        return m_enable;
    }
    inline bool isRepeat()
    {
        return m_repeat;
    }
    inline int getPriority()
    {
        return m_priority;
    }

protected:
    Slot();
    ~Slot();

    void connect(Signal* signal);
    void disconnect(Signal* signal);
    bool run(void* param);

    SLOT_FUNCTION m_slotFunction;
    unsigned int m_refCount;
    bool m_enable;
    bool m_repeat;
    int m_priority;

private:
    TSP_DISALLOW_COPY_AND_ASSIGN(Slot);
};

/*------------------------------------------------*/

class Signal
{
public:
    Signal();
    ~Signal();

    void run(void* param);
    void connect(Slot* slot);
    void disconnect(Slot* slot);

protected:
    std::list<Slot*>* m_connectedSlots;

private:
    TSP_DISALLOW_COPY_AND_ASSIGN(Signal);
};

/*------------------------------------------------*/

class SignalSet
{
public:
    SignalSet();
    virtual ~SignalSet();

    Signal* getSignal(int event_id);
    Slot* connectSignal(int event_id, const SLOT_FUNCTION& slot_function, int priority, bool repeat);
    void connectSignal(int event_id, Slot* slot);
    void emit(int event_id, void* param);

protected:
    std::map<int, Signal*>* m_signalMap;

private:
    TSP_DISALLOW_COPY_AND_ASSIGN(SignalSet);
};

TSP_NS_END

#endif /* defined(__smallworld__SignalSlot__) */
